package com.kddi.muldev.op;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.openid4java.message.ParameterList;

/**
 * @author liuqia
 *
 */
public class ProviderRegistrationServlet extends HttpServlet {

	private static final long serialVersionUID = 5838996252444604335L;
	
	private static final Log LOG = LogFactory.getLog(ProviderRegistrationServlet.class);

	private ServletContext context;
	
	public static final String DATA_FILE = "/opt/tomcat/openid_registration_info.properties";
	
	/**
	 * {@inheritDoc}
	 */
	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		context = config.getServletContext();
		LOG.debug("context: " + context);
	}

	/* (non-Javadoc)
	 * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		this.doPost(req, resp);
	}

	/* (non-Javadoc)
	 * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
	 */
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		HttpSession session = req.getSession();
		ParameterList requestp=(ParameterList) session.getAttribute("parameterlist");
		String openididentity=requestp.hasParameter("openid.identity") ? requestp.getParameterValue("openid.identity") : null;
		List<String> errFields = new ArrayList<String>();
		if ("Register".equals(req.getParameter("Register")) && checkParameter(req,errFields)){
			doRegister(req, openididentity);
			session.setAttribute("authenticatedAndApproved", Boolean.TRUE); 
   		 	req.setAttribute("_action", "complete");
   		 	RequestDispatcher rd = req.getRequestDispatcher("/auth");
   		 	rd.forward(req, resp);
		}else{
			resp.setCharacterEncoding("UTF-8");
			resp.setContentType("text/html");
			StringBuilder sb = new StringBuilder();
			sb.append("<html><head></head><body style='background-color:#ffffaa;'>");
			if (errFields.size()>0){
				sb.append("<h4 style='color:red'>Some fields are wrong!</h4>");
			}
			sb.append("<form action='"+context.getContextPath()+"/register' method='POST'><table>");
			sb.append("<tr><td style='"+(errFields.contains("loginid")?"color:red":"")+"'>LoginId:</td><td><input type='text' name='loginid' value='"+convertCharset(req.getParameter("loginid"))+"' /></td></tr>");
			sb.append("<tr><td style='"+(errFields.contains("password")?"color:red":"")+"'>Password:</td><td><input type='password' name='password' value='"+convertCharset(req.getParameter("password"))+"' /></td></tr>");
			sb.append("<tr><td style='"+(errFields.contains("repassword")?"color:red":"")+"'>Re Password:</td><td><input type='password' name='repassword' value='"+convertCharset(req.getParameter("repassword"))+"' /></td></tr>");
			sb.append("<tr><td>Nick Name:</td><td><input type='text' name='nickname' value='"+convertCharset(req.getParameter("nickname"))+"' /></td></tr>");
			sb.append("<tr><td>Email:</td><td><input type='text' name='email' value='"+convertCharset(req.getParameter("email"))+"' /></td></tr>");
			sb.append("<tr><td>Full Name:</td><td><input type='text' name='fullname' value='"+convertCharset(req.getParameter("fullname"))+"' /></td></tr>");
			sb.append("<tr><td>Date of birth:</td><td><input type='text' name='dob' value='"+convertCharset(req.getParameter("dob"))+"' /></td></tr>");
			sb.append("<tr><td>Gender:</td><td><input type='text' name='gender' value='"+convertCharset(req.getParameter("gender"))+"' /></td></tr>");
			sb.append("<tr><td>Postcode:</td><td><input type='text' name='postcode' value='"+convertCharset(req.getParameter("postcode"))+"' /></td></tr>");
			sb.append("<tr><td>Country:</td><td><input type='text' name='country' value='"+convertCharset(req.getParameter("country"))+"' /></td></tr>");
			sb.append("<tr><td>Language:</td><td><input type='text' name='language' value='"+convertCharset(req.getParameter("language"))+"' /></td></tr>");
			sb.append("<tr><td>Timezone:</td><td><input type='text' name='timezone' value='"+convertCharset(req.getParameter("timezone"))+"' /></td></tr>");
			sb.append("</table><input type='submit' value='Register' name='Register' /></form></body></html>");
			String respText = sb.toString();
			resp.setContentLength(respText.getBytes("UTF-8").length);
			resp.getWriter().write(respText);
			resp.flushBuffer();
		}
	}

	/**
	 * Check registration parameters
	 * @param req HttpServletRequest
	 * @return boolean
	 */
	private boolean checkParameter(HttpServletRequest req, List<String> errFields) {
		String loginid = req.getParameter("loginid");
		String password = req.getParameter("password");
		String repassword = req.getParameter("repassword");
		if (StringUtils.isEmpty(loginid)) {
			errFields.add("loginid");
		}
		if (StringUtils.isEmpty(password)) {
			errFields.add("password");
		}
		if (StringUtils.isEmpty(repassword) || !repassword.equals(password)) {
			errFields.add("repassword");
		}
		if (errFields.size() > 0) {
			return false;
		}else{
			return true;
		}
	}

	/**
	 * Register User Information about OpenID
	 * @param req
	 * @param openId
	 */
	private void doRegister(HttpServletRequest req, String openId) {
		StringBuilder sb = new StringBuilder();
		try {
			sb.append(encodeString(openId)).append("=").
			append(encodeString(req.getParameter("loginid"))).append(",").
			append(encodeString(req.getParameter("password"))).append(",").
			append(encodeString(req.getParameter("nickname"))).append(",").
			append(encodeString(req.getParameter("email"))).append(",").
			append(encodeString(req.getParameter("fullname"))).append(",").
			append(encodeString(req.getParameter("dob"))).append(",").
			append(encodeString(req.getParameter("gender"))).append(",").
			append(encodeString(req.getParameter("postcode"))).append(",").
			append(encodeString(req.getParameter("country"))).append(",").
			append(encodeString(req.getParameter("language"))).append(",").
			append(encodeString(req.getParameter("timezone"))).append(",").
			append(makeAuoneId()).append(System.getProperty("line.separator"));
			File file = FileUtils.getFile(DATA_FILE);
			FileUtils.writeStringToFile(file, sb.toString(), true);
		} catch (UnsupportedEncodingException e) {
			LOG.warn(e.getMessage(), e);
		} catch (IOException e) {
			LOG.warn(e.getMessage(), e);
		}
	}
	
	/**
	 * Make AuOneID
	 * @return String
	 */
	private String makeAuoneId() {
		StringBuilder sb = new StringBuilder();
		String base = "0123456789";
		Random rand = new Random();
		for (int i=0; i<11; i++) {
			sb.append(base.charAt(rand.nextInt(10)));
		}
		return sb.toString();
	}

	/**
	 * Convert Charset
	 * @param str String
	 * @return String
	 */
	private String convertCharset(String str) {
		if (StringUtils.isBlank(str)) {
			return "";
		}
		try {
			return new String(str.getBytes("ISO-8859-1"), "UTF-8");
		} catch (UnsupportedEncodingException e) {
			LOG.warn(e.getMessage(), e);
			return str;
		}
	}
	
	/**
	 * encodeString
	 * @param str
	 * @return
	 */
	private String encodeString(String str) {
		try {
			return URLEncoder.encode(str,"ISO-8859-1");
		} catch (UnsupportedEncodingException e) {
			LOG.warn(e.getMessage(), e);
			return "";
		}
	}
	
	

}
